"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

import hashlib, base64, re, urllib.parse, binascii
from datetime import datetime
from main.models import Uzanto
from django.conf import settings
from django.urls import reverse
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.mail import send_mail
from django.contrib.sites.models import Site


class UserToken:
    @staticmethod
    def check_token(token, confirm=True):
        str_token = urllib.parse.unquote(token)
        try:
            decoded = re.split('\|', base64.b64decode(str_token.encode('utf-8')).decode('utf-8'))
        except (UnicodeDecodeError, UnicodeEncodeError, binascii.Error):
            return None

        hash = decoded[2]
        del decoded[2]
        uuid = '-'.join(decoded)
        user = Uzanto.objects.filter(uuid=uuid)

        if not user.count():
            return None

        user = user[0]

        user_hash, hash_date = user.konfirmita_hash.split('|') if not user.konfirmita_hash is None else ['', '']

        if len(hash) and user_hash == hash:
            hash_date = datetime.strptime(hash_date, '%Y-%m-%d %H:%M:%S')

            # Если ключ активации выдан более чем 3 днями ранее,
            # то считаем его просроченным
            if (datetime.now() - hash_date).days > 3:
                return [user, False]

            if confirm:
                user.konfirmita_hash = None
                user.konfirmita = True
                user.malbona_retposhto = False
                user.save()
            return [user, True]

        return None

    @staticmethod
    def generate_token(user):
        if not user is None:
            sha = str(user.uuid) + str(user.id) + user.chefa_retposhto + datetime.now().isoformat()
            sha = hashlib.sha256(sha.encode('utf-8')).hexdigest()
            prepare = re.split('-', str(user.uuid))
            prepare.insert(2, sha)
            prepare = '|'.join(prepare)
            token = base64.b64encode(prepare.encode('utf-8')).decode('utf-8')
            user.konfirmita_hash = '%s|%s' % (sha, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            user.save()

            return urllib.parse.quote(token, safe='')

    @staticmethod
    def token_date(user):
        if not user is None\
                and not user.konfirmita_hash is None:
            hash_date = user.konfirmita_hash.split('|')
            hash_date = datetime.strptime(hash_date[1],'%Y-%m-%d %H:%M:%S') if len(hash_date) else None
            return hash_date

        return None


def send_confirmation_token(user, request, restarigo=False):
    if not user is None \
            and not request is None:
        uzanto = Uzanto.objects.values('id', 'uuid', 'unua_nomo__enhavo', 'familinomo__enhavo').get(uuid=user.uuid)
        token = UserToken.generate_token(user)
        server_name = request.META['SERVER_NAME']

        # Если сервер за прокси
        if ',' in server_name:
            server_name = server_name.split(',')[0].strip()

        page_name = 'registrado:konfirmo' if not restarigo else 'registrado:restarigo'

        if request.scheme == 'https' and request.META['SERVER_PORT'] != '443'\
                or request.scheme == 'http' and request.META['SERVER_PORT'] != '80':
            server_name += ':%s' % (request.META['SERVER_PORT'])

        token_url = '%s://%s%s' % (request.scheme,
                                   server_name,
                                   reverse(page_name, kwargs={'token': token}))
        data = {'uzanto': uzanto,
                'token_url': token_url,
                'restarigo': restarigo,
                'site_url': Site.objects.get_current() }
        email_body = """%s, %s %s
        %s %s""" % (_('Saluton'), uzanto['unua_nomo__enhavo'], uzanto['familinomo__enhavo'],
                    _('Por konfirmi la registron, alklaku la ligilon'),
                    token_url
                    )

        html_body = render_to_string('registrado/registrado_konfirmaretposto.html', data)
        send_mail(_('Konfirmo de la registrado') if not restarigo else 'Восстановление доступа к учетной записи',
                  email_body,
                  settings.EMAIL_NO_REPLY,
                  [user.chefa_retposhto],
                  fail_silently=True,
                  html_message=html_body
                  )
